package com.fr.similar;

import java.util.Arrays;
import java.util.List;

import org.apache.commons.collections.CollectionUtils;

import com.fr.similar.bean.PositionInfo;
import com.fr.similar.bean.SimilarityItem;
import com.fr.similar.bean.TalentInfo;

public class Similarity {
    private double titleWeight = 0.5;
    private double skillWeight = 0.2;
    private double industryWeight = 0.05;
    private double functionWeight = 0.1;
    private double salaryWeight = 0.1;
    private double cityWeight = 0.15;

    public Similarity() {

    }

    public Similarity(double title, double skill, double industry, double function, double salary, double city) {
        double total = title + skill + industry + function + salary + city;
        titleWeight = title / total;
        skillWeight = skill / total;
        industryWeight = industry / total;
        functionWeight = function / total;
        salaryWeight = salary / total;
        cityWeight = city / total;
    }

    protected SimilarityItem CreatePositionItem(PositionInfo p) {
        if (p == null) {
            return null;
        }
        SimilarityItem item = new SimilarityItem();
        item.setCity(Arrays.asList(p.getCityId()));
        // item.setFunction(Arrays.asList(p.getPositionTitleId()));
        item.setIndustry(Arrays.asList(p.getIndustryId()));
        item.setTitle(p.getPositionTitle());
        item.setSalaryMin(p.getMinActualSalary());
        item.setSalaryMax(p.getMaxActualSalary());
        return item;
    }

    protected SimilarityItem CreatePeopleItem(TalentInfo t) {
        if (t == null) {
            return null;
        }
        SimilarityItem item = new SimilarityItem();
        item.setCity(t.getExpectCityIds());
        // item.setFunction(t.getExpectFunction());
        item.setIndustry(t.getExpectIndustry());
        item.setSalaryMin(t.getExpectMinAnnualSalary());
        item.setSalaryMax(t.getExpectMaxAnnualSalary());
        item.setTitle(t.getExpectPositionTitles());
        return item;
    }

    public double calculate(SimilarityItem item1, SimilarityItem item2) {
        double score = 0;

        score += handleTitle(item1, item2);
        score += handleSkill(item1, item2);
        score += handleCity(item1, item2);
        score += handleIndustry(item1, item2);
        score += handleFunction(item1, item2);
        score += handleSalary(item1, item2);

        return score;
    }

    private double handleIndustry(SimilarityItem item1, SimilarityItem item2) {
        if (cantian(item1.getIndustry(), item2.getIndustry())) {
            return industryWeight;
        }
        return 0;
    }

    private double handleSalary(SimilarityItem item1, SimilarityItem item2) {
        double min1 = item1.getSalaryMin();
        double max1 = item1.getSalaryMax();
        double min2 = item2.getSalaryMin();
        double max2 = item2.getSalaryMax();
        if (min2 <= 0 || max2 <= 0) {
            return 0.1 * salaryWeight;
        } else if (Math.abs(min1 - min2) / min2 < 0.1 || Math.abs(max1 - max2) / max2 < 0.1) {
            return salaryWeight;
        } else if (Math.abs(min1 - min2) / min2 < 0.1 || Math.abs(max1 - max2) / max2 < 0.1) {
            return 0.8 * salaryWeight;
        }
        return 0.3 * salaryWeight;
    }

    private double handleFunction(SimilarityItem item1, SimilarityItem item2) {
        if (cantian(item1.getFunction(), item2.getFunction())) {
            return functionWeight;
        }
        return 0;
    }

    private double handleCity(SimilarityItem item1, SimilarityItem item2) {
        if (cantian(item1.getCity(), item2.getCity())) {
            return cityWeight;
        }
        return 0;
    }

    private double handleSkill(SimilarityItem item1, SimilarityItem item2) {
        // TODO Auto-generated method stub
        return skillWeight;
    }

    private double handleTitle(SimilarityItem item1, SimilarityItem item2) {
        // TODO Auto-generated method stub
        return titleWeight;
    }

    private boolean cantian(List<Long> a, List<Long> b) {
        if (CollectionUtils.isEmpty(a) || CollectionUtils.isEmpty(b)) {
            return false;
        }
        for (long l : a) {
            if (b.contains(l)) {
                return true;
            }
        }
        return false;
    }
}
